package threads;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class AtomicInt {

    private int i;

    public void set(int i) {
        this.i = i;
    }

    public int get() {
        return i;
    }

    // locked by "this"
    public synchronized void add(int a) {
        i += a;
    }
}

class MyRunnable implements Runnable {

    public static final int MAX = 100000;
    public static final int THREAD_COUNT = 10;
    public static final int THREAD_RANGE = MAX / THREAD_COUNT;
    private static final Object key = new Object();
    //public static int total = 0;
    public static int[] list;
    private int min, max;
    AtomicInt atomicInt;

    static {
        list = new int[MAX];
        Arrays.fill(list, 1);
    }

    MyRunnable(int min, int max, AtomicInt atomicInt) {
        this.min = min;
        this.max = max;
        this.atomicInt = atomicInt;
    }

    public int getTotal() {
        return atomicInt.get();
    }

    @Override
    public void run() {
        synchronized (atomicInt) {
            for (int i = min; i < max; i++) {


                atomicInt.set(atomicInt.get() + list[i]);

                System.out.println(i / THREAD_RANGE + ":" + atomicInt.get());
            }
        }
    }
}

    public class Threads {

        public static void main(String[] args) throws InterruptedException {
            Thread threads[] = new Thread[MyRunnable.THREAD_COUNT];

            AtomicInt ai = new AtomicInt();
            for (int i = 0; i < MyRunnable.THREAD_COUNT; i++) {
                int min = i * MyRunnable.THREAD_RANGE,
                        max = (i + 1) * MyRunnable.THREAD_RANGE;

                threads[i] = new Thread(new MyRunnable(min, max, ai));
            }

            for (Thread t : threads) {
                t.start();
            }

            boolean running;
            do {
                running = false;
                for (Thread t : threads) {
                    if (t.isAlive()) {
                        running = true;
                        break;
                    }
                }
                Thread.sleep(100);

                System.out.println("We have running threads. ");
            } while (running);

            System.out.println(ai.get());
//      ArrayList<Person> list = new ArrayList<>();
//      Person p1 = new Person("John", "Dough");
//      Person p2 = new Person("Jane", "Filo");
//      Person p3 = new Person("A", "Aardvark");
//      
//      list.add(p1);
//      list.add(p2);
//      list.add(p3);
//      
//      Collections.sort(list);
//      for ( Person p :list)
//          System.out.println(p);
//              
//      Collections.sort(list, new FirstNameComparator());
//      for ( Person p :list)
//          System.out.println(p);
        }
    }

    class FirstNameComparator implements Comparator<Person> {

        @Override
        public int compare(Person t1, Person t2) {
            int t = t1.first.compareTo(t2.first);
            if (t != 0) {
                return t;
            }
            return t1.last.compareTo(t2.last);
        }
    }

    class Person implements Comparable<Person> {

        Person(String f, String l) {
            last = l;
            first = f;
        }
        public String first, last;

        @Override
        public String toString() {
            return last + ", " + first;
        }

        @Override
        public int compareTo(Person that) {
            int t = this.last.compareTo(that.last);
            if (t != 0) {
                return t;
            }
            return this.first.compareTo(that.first);
        }
    
}